/**
 * Copyright (c) 2011-2017, James Zhan 詹波 (jfinal@126.com).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.jfinal.core;

import java.util.List;
import com.jfinal.config.Constants;
import com.jfinal.config.JFinalConfig;
import com.jfinal.config.Routes;
import com.jfinal.config.Plugins;
import com.jfinal.config.Handlers;
import com.jfinal.config.Interceptors;
import com.jfinal.kit.PathKit;
import com.jfinal.log.Log;
import com.jfinal.log.LogManager;
import com.jfinal.plugin.IPlugin;
import com.jfinal.template.Engine;

class Config {
	// 全局常量
	private static final Constants constants = new Constants();
	// 路由
	private static final Routes routes = new Routes() {
		public void config() {
		}
	};
	// 模板引擎
	private static final Engine engine = new Engine("JFinal Web");
	// 插件
	private static final Plugins plugins = new Plugins();
	// 拦截器
	private static final Interceptors interceptors = new Interceptors();
	// 责任链设计模式的一个应用，使用类似filter
	private static final Handlers handlers = new Handlers();
	// 日志
	private static Log log;

	// prevent new Config();
	// 私有化实例函数
	private Config() {
	}

	/**
	 * Config order: constant, route, engine, plugin, interceptor, handler<br>
	 * 配置顺序: constant, route, engine, plugin, interceptor, handler
	 */
	static void configJFinal(JFinalConfig jfinalConfig) {
		// 全局变量
		jfinalConfig.configConstant(constants);
		// 日志工厂
		initLogFactory();
		// 渲染引擎的基本属性
		initEngine();
		// 路由
		jfinalConfig.configRoute(routes);
		// 渲染引擎
		jfinalConfig.configEngine(engine);
		// 插件
		jfinalConfig.configPlugin(plugins);
		// 启动插件
		startPlugins(); // very important!!!
		// 拦截器
		jfinalConfig.configInterceptor(interceptors);
		// 处理器
		jfinalConfig.configHandler(handlers);
	}

	/**
	 * Set the default base template path and devMode by JFinal before
	 * configEngine(engine) invoked They can be reconfigured in
	 * configEngine(engine)
	 * 
	 * 在configEngine（引擎）调用之前，通过JFinal设置默认基本模板路径和devMode可以在configEngine（引擎）中重新配置
	 */
	private static void initEngine() {
		// 开发者模式开关
		// devMode==true时ActionReporter打印action信息，freemarker模板会及时刷新(2015-04-07,现在不知道还是这样么)
		engine.setDevMode(constants.getDevMode());
		// 设置模板的文件路径
		engine.setBaseTemplatePath(PathKit.getWebRootPath());
	}

	public static final Constants getConstants() {
		return constants;
	}

	public static final Routes getRoutes() {
		return routes;
	}

	public static final Engine getEngine() {
		return engine;
	}

	public static final Plugins getPlugins() {
		return plugins;
	}

	public static final Interceptors getInterceptors() {
		return interceptors;
	}

	public static Handlers getHandlers() {
		return handlers;
	}

	private static void startPlugins() {
		// 所有的插件集合
		List<IPlugin> pluginList = plugins.getPluginList();
		if (pluginList == null) {
			return;
		}

		/*for (IPlugin plugin : pluginList) {
			try {
				// process ActiveRecordPlugin devMode
				// 数据库插件的启动
				if (plugin instanceof com.jfinal.plugin.activerecord.ActiveRecordPlugin) {
					com.jfinal.plugin.activerecord.ActiveRecordPlugin arp = (com.jfinal.plugin.activerecord.ActiveRecordPlugin) plugin;
					// 开发者模式开关
					if (arp.getDevMode() == null) {
						arp.setDevMode(constants.getDevMode());
					}
				}
				// 如果启动失败了
				if (plugin.start() == false) {
					String message = "Plugin start error: " + plugin.getClass().getName();
					log.error(message);
					throw new RuntimeException(message);
				}
			} catch (Exception e) {
				String message = "Plugin start error: " + plugin.getClass().getName() + ". \n" + e.getMessage();
				log.error(message, e);
				throw new RuntimeException(message, e);
			}
		}*/
		pluginList.stream().forEach(plugin -> {
			try {
				// process ActiveRecordPlugin devMode
				// 数据库插件的启动
				if (plugin instanceof com.jfinal.plugin.activerecord.ActiveRecordPlugin) {
					com.jfinal.plugin.activerecord.ActiveRecordPlugin arp = (com.jfinal.plugin.activerecord.ActiveRecordPlugin) plugin;
					// 开发者模式开关
					if (arp.getDevMode() == null) {
						arp.setDevMode(constants.getDevMode());
					}
				}
				// 如果启动失败了
				if (plugin.start() == false) {
					String message = "Plugin start error: " + plugin.getClass().getName();
					log.error(message);
					throw new RuntimeException(message);
				}
			} catch (Exception e) {
				String message = "Plugin start error: " + plugin.getClass().getName() + ". \n" + e.getMessage();
				log.error(message, e);
				throw new RuntimeException(message, e);
			}
		});
	}

	private static void initLogFactory() {
		// 单例的日志工厂
		LogManager.me().init();
		// Config的日志对象
		log = Log.getLog(Config.class);
		// JFinalFilter的日志对象
		JFinalFilter.initLog();
	}
}
